package de.fhkl.strokeprotocol.io;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.concurrent.Semaphore;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.fhkl.strokeprotocol.messages.IMessage;

/**
 * Allows to send the messages of the WhatsStroke protocol.
 */
public class StrokeOutputWriter
{
	/** Init logger for this class */
	private static Logger sLogger = LoggerFactory.getLogger(StrokeOutputWriter.class);
	
	/** ObjectOutputStream to write in */
	private ObjectOutputStream mOut;

	/** This semaphore ensures that we can only send one message at a time. */
	private Semaphore mSemaphore;

	/**
	 * Allows to send the messages of the WhatsStroke protocol. Creates an
	 * ObjectOutputStream that writes to the specified OutputStream.
	 * 
	 * @param out
	 *            OutputStream to write in
	 * @throws IOException
	 *             if an I/O error occurs while writing stream header
	 */
	public StrokeOutputWriter(OutputStream out) throws IOException
	{
		mOut = new ObjectOutputStream(out);
		mSemaphore = new Semaphore(1, true);
	}

	/**
	 * Sends a message.
	 * 
	 * @throws Exception
	 */
	public void send(IMessage message) throws Exception
	{
		mSemaphore.acquire();
		
		mOut.writeObject(message);
		mOut.flush();

		mSemaphore.release();
	}

	/**
	 * Closes the output stream.
	 * 
	 * @throws IOException
	 */
	public void close() throws IOException
	{
		sLogger.info("Closing StrokeOutputWriter...");
		
		mOut.close();
		mOut = null;
		
		sLogger.info("StrokeOutputWriter successfully closed.");
	}
}
